<template>
  <div>
    <span id="shareText"></span>
  </div>

  <t-dialog v-model:visible="materialVisible" mode="modal" header="添加直播素材" :footer="false">
    <t-button @click="OpenCameraVideoList">
      打开摄像头
      <LogoWindowsFilledIcon />
    </t-button>
    <t-button @click="OpenAudioList"> 打开音频 </t-button>

    <t-button @click="OpenDisplayMedia"> 共享屏幕 </t-button>
  </t-dialog>

  <!-- 添加素材 模态框 -->
  <div>
    <!-- 摄像头 -->
    <div>
      <t-dialog
        v-model:visible="cameraFormData.visible"
        draggable
        mode="modal"
        header="添加直播素材"
        :on-confirm="OpenCameraVideo"
      >
        <template #body>
          <t-form-item label="名称">
            <t-input v-model="cameraFormData.name" placeholder="摄像头"></t-input>
          </t-form-item>

          <t-form-item label="设备选择">
            <t-select v-model="cameraFormData.deviceId" placeholder="请选择">
              <t-option
                v-for="item in cameraFormData.deviceArr"
                :key="item.id"
                :value="item.id"
                :label="item.label"
              ></t-option>
            </t-select>
          </t-form-item>
        </template>
      </t-dialog>
    </div>
    <!-- 音频 -->
    <div>
      <t-dialog
        v-model:visible="audioFormData.visible"
        draggable
        mode="modal"
        header="添加直播素材"
        :on-confirm="OpenAudio"
      >
        <template #body>
          <t-form-item label="名称">
            <t-input v-model="audioFormData.name" placeholder="音频"></t-input>
          </t-form-item>

          <t-form-item label="设备选择">
            <t-select v-model="audioFormData.deviceId" placeholder="请选择">
              <t-option
                v-for="item in audioFormData.deviceArr"
                :key="item.id"
                :value="item.id"
                :label="item.label"
              ></t-option>
            </t-select>
          </t-form-item>
        </template>
      </t-dialog>
    </div>
  </div>

  <div id="app">
    <!--本地视频流-->
    <div style="display: flex; justify-content: center; align-items: center; height: 100%">
      <div>
        <div
          style="
            width: 1152px;
            height: 648px;
            background-color: #f0f0f0;
            border: 1px solid #ccc;
            position: relative;
            overflow: hidden;
          "
        >
          <DraggableContainer style="background-color: #18191c">
            <Audio v-for="item in deviceRefList.audio" :key="item.key" :ref="item.key"></Audio>
            <Video v-for="item in deviceRefList.video" :key="item.key" :ref="item.key"></Video>
          </DraggableContainer>
        </div>
        <div
          style="
            height: 100px;
            border-radius: 5px;
            border-style: solid;
            border-width: 1px;
            border-color: #fff;
            background-color: rgba(255, 255, 255, 0.8);
          "
        >
          码率设置
          <t-button @click="handleOpenVideo"> 我要开播 </t-button>
        </div>
      </div>

      <div
        style="
          width: 385px;
          height: 748px;
          border-radius: 5px;
          border-style: solid;
          border-width: 1px;
          border-color: #fff;
          background-color: rgba(255, 255, 255, 0.8);
          margin-left: 10px;
        "
      >
        <h3 style="padding: 10px; margin: 0; font-size: inherit; font-weight: inherit">素材列表</h3>
        <div style="display: flex; flex-direction: column; justify-content: space-between">
          <div>
            <t-list :split="true">
              <!-- 音频已添加列表 -->
              <t-list-item v-for="audio in deviceRefList.audio" :key="audio.key">
                <!-- <t-list-item-meta :description="audio.name"></t-list-item-meta> -->
                {{ audio.name }}
                <template #action>
                  <t-button shape="circle" variant="text" @click="DeleteDevice('audio', audio.key)"
                    ><DeleteIcon slot="icon"
                  /></t-button>
                </template>
              </t-list-item>
              <!-- 视频已添加列表 -->
              <draggable v-model="deviceRefList.video" group="people" item-key="id">
                <template #item="{ element }">
                  <t-list-item>
                    <!-- <t-list-item-meta :description="element.name"></t-list-item-meta> -->
                    {{ element.name }}
                    <template #action>
                      <t-button shape="circle" variant="text" @click="DeleteDevice('video', element.key)"
                        ><DeleteIcon slot="icon"
                      /></t-button>
                    </template>
                  </t-list-item>
                </template>
              </draggable>
            </t-list>
          </div>
          <div style="margin-top: 100px">
            <t-button @click="AddMaterial">添加素材</t-button>
          </div>
        </div>
      </div>
    </div>

    <hr />

    <!-- 远程端视频流 -->
    <div style="display: flex; justify-content: center; align-items: center; height: 100%">
      <div
        :style="`width: ${canvasWidth * 0.5}px; height: ${
          canvasHeight * 0.5
        }px; background-color: #f0f0f0; border: 1px solid #ccc`"
      >
        <!-- <div id="remoteVideo" style="width: 100%; height: 100%;"></div> -->
        <video id="remoteVideo" style="width: 100%; height: 100%" autoplay playsinline>远程视频</video>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, nextTick } from 'vue'
import Video from '@/components/video.vue'
import Audio from '@/components/audio.vue'

import DraggableContainer from 'vue3-draggable-resizable'
// import Vue3DraggableResizable from "vue3-draggable-resizable"
// import 'vue3-draggable-resizable/dist/Vue3DraggableResizable.css'
import { doOfferPush } from '@/utils/rtc_push'
import { MessagePlugin } from 'tdesign-vue-next'
import * as workerTimers from 'worker-timers'
import { v4 as uuidv4 } from 'uuid'
import draggable from 'vuedraggable'

import { DeleteIcon, LogoWindowsFilledIcon } from 'tdesign-icons-vue-next'

export default defineComponent({
  name: 'Home',
  components: { LogoWindowsFilledIcon, Video, Audio, draggable, DeleteIcon },
  data() {
    return {
      canvasWidth: 1152,
      canvasHeight: 648,

      cameraFormData: {
        name: '摄像头',
        deviceArr: [],
        deviceId: null,
        visible: false,
      },
      audioFormData: {
        name: '音频',
        deviceArr: [],
        deviceId: null,
        visible: false,
      },
      deviceRefList: {
        // display: {},
        // camera: {},
        video: [],
        audio: [],
      },
      materialVisible: false,
      roomId: Math.random().toString(36).substring(2),

      userId: Math.random().toString(36).substring(2),
    }
  },

  mounted(){
    this.InitDevices()
  },
  methods: {
    DeleteDevice(deviceType: string, deviceKey: string) {
      const indexToDelete = this.deviceRefList[deviceType].findIndex((item: any) => item.key === deviceKey)
      // 使用splice方法删除该元素
      if (indexToDelete !== -1) {
        this.deviceRefList[deviceType].splice(indexToDelete, 1)
      }
    },
    AddMaterial() {
      this.materialVisible = true
    },

    OpenAudioList() {
      // 打开音频列表
      var _this = this
      this.audioFormData.deviceArr = []
      this.audioFormData.visible = true
      navigator.mediaDevices.enumerateDevices().then(function (devices) {
        devices.forEach(function (device) {
          if (device.kind == 'audioinput') {
            _this.audioFormData.deviceArr.push({
              label: device.label,
              id: device.deviceId,
            })
          }
        })
      })
    },
    OpenAudio() {
      // 打开音频
      var componentRef = 'audioComponentRef-' + uuidv4()
      this.materialVisible = false
      this.audioFormData.visible = false
      this.deviceRefList.audio.push({ key: componentRef, name: this.audioFormData.name })

      this.$nextTick(() => {
        this.$refs[componentRef][0].OpenAudio(this.audioFormData.deviceId)
      })
    },

    InitDevices() {
      // 初始化设备
      navigator.mediaDevices.getUserMedia({ video: true, audio:true }).then(function (stream) {
        if (stream.active) {
          var tracks = stream.getTracks()
          tracks.forEach(function (track) {
            track.stop()
          })
        }
      })
    },

    OpenCameraVideoList() {
      // 打开摄像头列表

      var _this = this
      _this.cameraFormData.deviceArr = []
      _this.cameraFormData.visible = true
      navigator.mediaDevices.enumerateDevices().then(function (devices) {
        devices.forEach(function (device) {
          if (device.kind == 'videoinput') {
            _this.cameraFormData.deviceArr.push({
              label: device.label,
              id: device.deviceId,
            })
          }
        })
      })
    },
    OpenCameraVideo() {
      // 打开摄像头
      var componentRef = 'cameraComponentRef-' + uuidv4()
      this.materialVisible = false
      this.cameraFormData.visible = false
      this.deviceRefList.video.push({ key: componentRef, name: this.cameraFormData.name })

      this.$nextTick(() => {
        this.$refs[componentRef][0].OpenCameraVideo(this.cameraFormData.deviceId)
      })
    },

    OpenDisplayMedia() {
      // 打开窗口
      this.materialVisible = false
      var componentRef = 'displayComponentRef-' + uuidv4()
      this.deviceRefList.video.push({ key: componentRef, name: '窗口' })

      this.$nextTick(() => {
        this.$refs[componentRef][0].OpenDisplayMedia()
      })
    },

    mergerCanvas() {
      var multiple = 2
      var _this = this
      const canvas = document.createElement('canvas')
      const ctx = canvas.getContext('2d')
      canvas.width = this.canvasWidth * multiple
      canvas.height = this.canvasHeight * multiple

      // 将屏幕共享和摄像头流绘制到Canvas上
      function drawStreams() {
        ctx.clearRect(0, 0, canvas.width, canvas.height)

        _this.deviceRefList.video.forEach((line: any) => {
          var item = _this.$refs[line.key][0].data
          if (item.element !== null) {
            ctx.drawImage(item.element, item.x * multiple, item.y * multiple, item.w * multiple, item.h * multiple)
          }
        })
      }

      workerTimers.setInterval(() => {
        drawStreams()
      }, 1000 / 60)

      // 在页面中显示Canvas
      // document.getElementById('remoteVideo').appendChild(canvas);

      return canvas
    },

    async handleOpenVideo() {
      const canvas = this.mergerCanvas()
      const canvasStream = canvas.captureStream()

      // 音频处理
      var audioTracksList = []
      this.deviceRefList.audio.forEach((line: any) => {
        audioTracksList.push(this.$refs[line.key][0].data.stream.getAudioTracks()[0])
      })

      const audioContext = new AudioContext()
      const blankAudioTrack = audioContext.createMediaStreamDestination().stream.getAudioTracks()[0]
      audioTracksList.push(blankAudioTrack)
      var mergeAudioTracks = new MediaStream(audioTracksList)

      canvasStream.addTrack(mergeAudioTracks.getAudioTracks()[0])

      var remoteVideo = document.getElementById('remoteVideo') as HTMLVideoElement
      remoteVideo.srcObject = canvasStream
      doOfferPush(this.userId, this.roomId, canvasStream)
    },
  },
})
</script>

<style>
body {
  background-image: url(/assets/background.jpg);
  width: 1440px;
  margin: 100px auto;
}
</style>
